package com.easylinkin.linkappapi.grid.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.core.enums.EWhether;
import com.easylinkin.linkappapi.grid.entity.GridReportWeek;
import com.easylinkin.linkappapi.grid.entity.GridReportWeekDetail;
import com.easylinkin.linkappapi.grid.entity.GridReportWeekUser;
import com.easylinkin.linkappapi.grid.mapper.GridReportWeekUserMapper;
import com.easylinkin.linkappapi.grid.models.vo.GridReportWeekUserInfoVO;
import com.easylinkin.linkappapi.grid.service.IGridReportWeekUserService;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import com.easylinkin.linkappapi.security.service.LinkappUserService;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 网格周报人员指定表 服务实现类
 *
 * @author kuyujie
 * @since 2024-05-20
 */
@Slf4j
@Setter(onMethod_ = @Resource)
@Service
public class GridReportWeekUserServiceImpl extends ServiceImpl<GridReportWeekUserMapper, GridReportWeekUser> implements IGridReportWeekUserService {

    private LinkappUserService linkappUserService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveData(GridReportWeek gridReportWeek, List<String> userIdList) {
        LocalDateTime now = LocalDateTime.now();

        List<GridReportWeekUser> entityList = new ArrayList<>(userIdList.size());

        for (int i = 0; i < userIdList.size(); i++) {
            String userId = userIdList.get(i);

            GridReportWeekUser entity = GridReportWeekUser.builder()
                    .reportId(gridReportWeek.getId())
                    .userId(userId)
                    .sort(i)
                    .tenantId(gridReportWeek.getTenantId())
                    .creatorId(gridReportWeek.getCreatorId())
                    .creator(gridReportWeek.getCreator())
                    .createTime(now)
                    .modifyId(gridReportWeek.getModifyId())
                    .modifier(gridReportWeek.getModifier())
                    .modifyTime(now)
                    .build();

            entityList.add(entity);
        }

        return this.saveBatch(entityList);
    }

    @Override
    public List<GridReportWeekUserInfoVO> listByReportId(Long reportId, LocalDateTime submitDeadline) {
        List<GridReportWeekUserInfoVO> userList = baseMapper.selectListByReportId(reportId);

        Set<String> userIdSet = userList.stream().map(GridReportWeekUserInfoVO::getUserId).collect(Collectors.toSet());
        Map<String, LinkappUser> userMap = linkappUserService.mapUserByIds(userIdSet);

        LocalDateTime now = LocalDateTime.now();
        userList.parallelStream().forEach(item -> {
            if (ObjectUtil.isNull(item.getSubmitTime()) && now.isAfter(submitDeadline)) {
                item.setIsTimeout(EWhether.YES.getCode());
            } else {
                item.setIsTimeout(EWhether.NO.getCode());
            }

            LinkappUser linkappUser = userMap.get(item.getUserId());
            if (ObjectUtil.isNotNull(linkappUser)) {
                item.setNickname(linkappUser.getNickname());
            }
        });

        return userList;
    }

    @Override
    public GridReportWeekUser getByReportIdUserId(Long reportId, String userId) {
        return baseMapper.selectOne(Wrappers.<GridReportWeekUser>lambdaQuery()
                .eq(GridReportWeekUser::getReportId, reportId)
                .eq(GridReportWeekUser::getUserId, userId)
                .last("limit 1")
        );
    }

    @Override
    public boolean updateSubmit(GridReportWeekDetail reportWeekDetail) {
        GridReportWeekUser entity = GridReportWeekUser.builder()
                .id(reportWeekDetail.getReportUserId())
                .submitTime(reportWeekDetail.getModifyTime())
                .build();

        return this.updateById(entity);
    }
}